package com.db.nearcache.remote;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.db.nearcache.cache.Cache;

/**
 * Cache proxy backed by a remote cache.
 */

// TODO implement heartbeat to detect if server is down.

@SuppressWarnings("serial")
public class RemoteCacheAdapter extends UnicastRemoteObject implements Cache, RemoteCacheObserver {

	private ConcurrentHashMap<String, Object> cache = new ConcurrentHashMap<>();
	private Logger logger = Logger.getLogger(RemoteCacheAdapter.class.getName());

	public RemoteCacheAdapter(ObservableRemoteCache remoteCache) throws RemoteException {
		remoteCache.subscribe(this);
		cache.putAll(remoteCache.snapshot());
	}

	@Override
	public void put(String key, Object value) {
		throw new UnsupportedOperationException("put is not supported");
	}

	@Override
	public Object get(String key) {
		return cache.get(key);
	}

	@Override
	public void update(String key, Object value) throws RemoteException {
		if (logger.isLoggable(Level.INFO)) {
			logger.info(String.format("rcvd update (%s => %s)%n", key, value));
		}
		cache.put(key, value);
	}

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();
		for (Entry<String, Object> entry : cache.entrySet()) {
			sb.append(String.format("(%s => %s)%n", entry.getKey(), entry.getValue()));
		}

		return sb.toString();
	}

}
